/******************************************************************************* * Copyright (c) 2000, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Jan-Hendrik Diederich, Bredex GmbH - bug 201052 *******************************************************************************/ package org.eclipse.ui.internal.dialogs; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.ui.IPluginContribution; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.activities.WorkbenchActivityHelper; import org.eclipse.ui.internal.WorkbenchImages; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.model.AdaptableList; import org.eclipse.ui.model.IWorkbenchAdapter; import org.eclipse.ui.wizards.IWizardCategory; import org.eclipse.ui.wizards.IWizardDescriptor; /** * Instances of this class are a collection of WizardCollectionElements, * thereby facilitating the definition of tree structures composed of these * elements. Instances also store a list of wizards. */ public class WizardCollectionElement extends AdaptableList implements IPluginContribution, IWizardCategory { private String id; private String pluginId; private String name; private WizardCollectionElement parent; private AdaptableList wizards = new AdaptableList(); private IConfigurationElement configElement; /** * Creates a new <code>WizardCollectionElement</code>. Parent can be * null. * @param id the id * @param pluginId the plugin * @param name the name * @param parent the parent */ public WizardCollectionElement(String id, String pluginId, String name, WizardCollectionElement parent) { this.name = name; this.id = id; this.pluginId = pluginId; this.parent = parent; } /** * Creates a new <code>WizardCollectionElement</code>. Parent can be * null. * * @param element * @param parent * @since 3.1 */ public WizardCollectionElement(IConfigurationElement element, WizardCollectionElement parent) { configElement = element; id = configElement.getAttribute(IWorkbenchRegistryConstants.ATT_ID); this.parent = parent; } private WizardCollectionElement(WizardCollectionElement input, AdaptableList wizards) { this(input.id, input.pluginId, input.name, input.parent); this.configElement = input.configElement; this.wizards = wizards; for (Object child : input.children) { children.add(child); } } /** * Adds a wizard collection to this collection. */ @Override public AdaptableList add(IAdaptable a) { if (a instanceof WorkbenchWizardElement) { wizards.add(a); } else { super.add(a); } return this; } /** * Remove a wizard from this collection. */ @Override public void remove(IAdaptable a) { if (a instanceof WorkbenchWizardElement) { wizards.remove(a); } else { super.remove(a); } } /** * Returns the wizard collection child object corresponding to the passed * path (relative to this object), or <code>null</code> if such an object * could not be found. * * @param searchPath * org.eclipse.core.runtime.IPath * @return WizardCollectionElement */ public WizardCollectionElement findChildCollection(IPath searchPath) { String searchString = searchPath.segment(0); for (Object element : getChildren(null)) { WizardCollectionElement currentCategory = (WizardCollectionElement) element; if (currentCategory.getId().equals(searchString)) { if (searchPath.segmentCount() == 1) { return currentCategory; } return currentCategory.findChildCollection(searchPath .removeFirstSegments(1)); } } return null; } /** * Returns the wizard category corresponding to the passed * id, or <code>null</code> if such an object could not be found. * This recurses through child categories. * * @param id the id for the child category * @return the category, or <code>null</code> if not found * @since 3.1 */ public WizardCollectionElement findCategory(String id) { for (Object element : getChildren(null)) { WizardCollectionElement currentCategory = (WizardCollectionElement) element; if (id.equals(currentCategory.getId())) { return currentCategory; } WizardCollectionElement childCategory = currentCategory.findCategory(id); if (childCategory != null) { return childCategory; } } return null; } /** * Returns this collection's associated wizard object corresponding to the * passed id, or <code>null</code> if such an object could not be found. * * @param searchId the id to search on * @param recursive whether to search recursivly * @return the element */ public WorkbenchWizardElement findWizard(String searchId, boolean recursive) { for (Object wizard : getWizards()) { WorkbenchWizardElement currentWizard = (WorkbenchWizardElement) wizard; if (currentWizard.getId().equals(searchId)) { return currentWizard; } } if (!recursive) { return null; } for (Iterator iterator = children.iterator(); iterator.hasNext();) { WizardCollectionElement child = (WizardCollectionElement) iterator .next(); WorkbenchWizardElement result = child.findWizard(searchId, true); if (result != null) { return result; } } return null; } /** * Returns an object which is an instance of the given class associated * with this object. Returns <code>null</code> if no such object can be * found. */ @Override public <T> T getAdapter(Class<T> adapter) { if (adapter == IWorkbenchAdapter.class) { return adapter.cast(this); } return Platform.getAdapterManager().getAdapter(this, adapter); } /** * Returns the unique ID of this element. */ @Override public String getId() { return id; } /** * Returns the label for this collection. */ @Override public String getLabel(Object o) { return configElement != null ? configElement .getAttribute(IWorkbenchRegistryConstants.ATT_NAME) : name; } /** * Returns the logical parent of the given object in its tree. */ @Override public Object getParent(Object o) { return parent; } @Override public IPath getPath() { if (parent == null) { return new Path(""); //$NON-NLS-1$ } return parent.getPath().append(getId()); } @Override public IWizardDescriptor [] getWizards() { return getWizardsExpression((IWizardDescriptor[]) wizards .getTypedChildren(IWizardDescriptor.class)); } /** * Takes an array of <code>IWizardDescriptor</code> and removes all * entries which fail the Expressions check. * * @param wizardDescriptors Array of <code>IWizardDescriptor</code>. * @return The array minus the elements which faled the Expressions check. */ private IWizardDescriptor[] getWizardsExpression(IWizardDescriptor[] wizardDescriptors) { int size = wizardDescriptors.length; List result = new ArrayList(size); for (int i = 0; i < size; i++) { if (!WorkbenchActivityHelper.restrictUseOf(wizardDescriptors[i])) result.add(wizardDescriptors[i]); } return (IWizardDescriptor[])result .toArray(new IWizardDescriptor[result.size()]); } /** * Return the wizards minus the wizards which failed the expressions check. * * @return the wizards * @since 3.1 */ public WorkbenchWizardElement [] getWorkbenchWizardElements() { return getWorkbenchWizardElementsExpression( (WorkbenchWizardElement[]) wizards .getTypedChildren(WorkbenchWizardElement.class)); } /** * Takes an array of <code>WorkbenchWizardElement</code> and removes all * entries which fail the Expressions check. * * @param workbenchWizardElements Array of <code>WorkbenchWizardElement</code>. * @return The array minus the elements which faled the Expressions check. */ private WorkbenchWizardElement[] getWorkbenchWizardElementsExpression( WorkbenchWizardElement[] workbenchWizardElements) { int size = workbenchWizardElements.length; List result = new ArrayList(size); for (int i=0; i<size; i++) { WorkbenchWizardElement element = workbenchWizardElements[i]; if (!WorkbenchActivityHelper.restrictUseOf(element)) result.add(element); } return (WorkbenchWizardElement[])result.toArray(new WorkbenchWizardElement[result.size()]); } /** * Returns true if this element has no children and no wizards. * * @return whether it is empty */ public boolean isEmpty() { return size() == 0 && wizards.size() == 0; } /** * For debugging purposes. */ @Override public String toString() { StringBuffer buf = new StringBuffer("WizardCollection, "); //$NON-NLS-1$ buf.append(children.size()); buf.append(" children, "); //$NON-NLS-1$ buf.append(wizards.size()); buf.append(" wizards"); //$NON-NLS-1$ return buf.toString(); } @Override public ImageDescriptor getImageDescriptor(Object object) { return WorkbenchImages.getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER); } @Override public String getLocalId() { return getId(); } @Override public String getPluginId() { return configElement != null ? configElement.getNamespace() : pluginId; } @Override public IWizardCategory getParent() { return parent; } @Override public IWizardCategory[] getCategories() { return (IWizardCategory []) getTypedChildren(IWizardCategory.class); } /** * Return the collection elements. * * @return the collection elements * @since 3.1 */ public WizardCollectionElement [] getCollectionElements() { return (WizardCollectionElement[]) getTypedChildren(WizardCollectionElement.class); } /** * Return the raw adapted list of wizards. * * @return the list of wizards * @since 3.1 */ public AdaptableList getWizardAdaptableList() { return wizards; } @Override public String getLabel() { return getLabel(this); } /** * Return the configuration element. * * @return the configuration element * @since 3.1 */ public IConfigurationElement getConfigurationElement() { return configElement; } /** * Return the parent collection element. * * @return the parent * @since 3.1 */ public WizardCollectionElement getParentCollection() { return parent; } @Override public IWizardDescriptor findWizard(String id) { return findWizard(id, true); } @Override public IWizardCategory findCategory(IPath path) { return findChildCollection(path); } /** * The helper method used to filter <code>WizardCollectionElement</code> * using <code>ViewerFilter</code>.<br> * It returns the result in the following way:<br> * - if some of the wizards from the input collection is skipped by the * viewerFilter then the modified copy of the collection (without skipped * wizards) is returned<br> * - when all wizards are skipped then null will be returned<br> * - if none of the wizards is skipped during filtering then the original * input collection is returned * * @param viewer * the Viewer used by <code>ViewerFilter.select</code> method * @param viewerFilter * the ViewerFilter * @param inputCollection * collection to filter * @return inputCollection, modified copy of inputCollection or null * */ static WizardCollectionElement filter(Viewer viewer, ViewerFilter viewerFilter, WizardCollectionElement inputCollection) { AdaptableList wizards = null; for (Object child : inputCollection.getWizardAdaptableList().getChildren()) { if (viewerFilter.select(viewer, inputCollection, child)) { if (wizards == null) { wizards = new AdaptableList(); } wizards.add((IAdaptable) child); } } if (wizards == null) { if (inputCollection.getChildren().length > 0) { return new WizardCollectionElement(inputCollection, new AdaptableList()); } return null; } if (inputCollection.getWizardAdaptableList().size() == wizards.size()) { return inputCollection; } return new WizardCollectionElement(inputCollection, wizards); } }